/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using antiufo.HttpPost;
using System.Collections.Specialized;
using System.Net;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of ArticleCategoryStore.
	/// </summary>
	public class ArticleCategoryStore : IStore<ArticleCategory>
	{		
		private HtmlWeb _client;
		
		private JsonDatabase db;				
		
		public ArticleCategoryStore(Site site,HtmlWeb client)
		{
			db = new JsonDatabase("sites/" + site.Name + "/articles_categories");
			_site = site;
			_client = client;
		}				
		
		private Site _site;
		public Site site {
			get { return _site; }
			set { _site = value; }
		}
		
		public void PersistItems(List<ArticleCategory> items)
		{
			db.Write<List<ArticleCategory>>(items,_site.Name);
		}
		
		public void Truncate()
		{
			ArticleCategory[] _categories = LoadItems();
			
			foreach(ArticleCategory category in _categories)
			{
				if(!DeleteItem(category.articles_categories_id))
				{
//					throw new Exception("Could not delete the ArticleCategory " + category.articles_categories_name + " in site " + _site.Name);
				}
			}
			
			db.Truncate();
		}
		
		public bool DeleteItem(string itemId)
		{
			string url = _site.Url + "/admin/json.php?action=delete_article_category&articles_categories_id="  + itemId + "&module=articles_categories";
			HtmlDocument doc = _client.Load(url);

			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "success") {
					var response = bool.Parse(json[key].ToString());
					if (response) {
						db.Delete<UnitClass>(itemId);
					}

					return response;
				}
			}

			throw new Exception("Could not delete the ArticleCategory " + itemId + " in site " + _site.Name);
		}
		
		public void PersistItem(ArticleCategory item)
		{
			db.Write<ArticleCategory>(item,item.articles_categories_id);
		}
		
		public bool MoveItem(string itemId, string folderId)
		{
			throw new NotImplementedException();
		}				
		
		public ArticleCategory[] LoadItems()
		{
			ArticleCategory[] items = db.Read<ArticleCategory>();
			foreach(ArticleCategory item in items)
			{
				item.Store = this;
			}
			return items;
		}
		
		public ArticleCategory LoadItem(string itemId)
		{
			ArticleCategory item = db.Read<ArticleCategory>(itemId);
			if (item != null) {
				item.Store = this;
				return item;
			}

			return null;
		}
		
		public bool Contains(ArticleCategory item)
		{
			throw new NotImplementedException();
		}
		
		private List<ArticleCategory> categories;
		public List<ArticleCategory> GetItems()
		{			
			db.Truncate();
			categories = new List<ArticleCategory>();
			
			string url = _site.Url + "/admin/json.php?action=list_articles_categories&module=articles_categories";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						ArticleCategory category = GetItem(record["articles_categories_id"].ToString());
						categories.Add(category);
						PersistItem(category);
					}
				}
			}
			
			PersistItems(categories);
			
			return categories;
		}

		public List<ArticleCategory> DownloadItems()
		{						
			categories = new List<ArticleCategory>();
			
			string url = _site.Url + "/admin/json.php?action=list_articles_categories&module=articles_categories";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						ArticleCategory category = GetItem(record["articles_categories_id"].ToString());
						categories.Add(category);						
					}
				}
			}						
			
			return categories;
		}
		
		public ArticleCategory GetItem(string itemId)
		{			
			string url = _site.Url + "/admin/json.php?action=load_articles_categories&articles_categories_id=" + itemId + "&module=articles_categories";                                      
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");

			try {
				JObject json = (JObject)JsonConvert.DeserializeObject(node.InnerText);
				foreach (JProperty property in json.Properties()) {
					if (property.Name == "data") {
						var val = property.Value.ToString();
						ArticleCategory category = new ArticleCategory(val);
						category.Store = this;
						return category;
					}
				}

				throw new Exception("Could not load the category " + itemId);
			} catch (Exception ex) {
				throw ex;
			}
		}
		
		public bool UpdateItem(ArticleCategory item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("articles_categories_id",item.articles_categories_id);
			post.AddField("articles_categories_status",item.articles_categories_status);
			post.AddField("articles_categories_order",item.articles_categories_order);
			post.AddField("module", "articles_categories");
			post.AddField("action", "save_articles_category");
			
			foreach(string key in item.articles_categories_names.Keys)
			{
				post.AddField(key,item.articles_categories_names[key]);
			}
			
			foreach(string key in item.articles_categories_urls.Keys)
			{
				post.AddField(key,item.articles_categories_urls[key]);
			}

			foreach(string key in item.page_titles.Keys)
			{
				post.AddField(key,item.page_titles[key]);
			}

			foreach(string key in item.meta_keywordss.Keys)
			{
				post.AddField(key,item.meta_keywordss[key]);
			}		
			
			foreach(string key in item.meta_descriptions.Keys)
			{
				post.AddField(key,item.meta_descriptions[key]);
			}	
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						return bool.Parse(json[key].ToString());
					}
				}
			}		
			
			throw new Exception("Could not update the ArticleCategory " + item.articles_categories_name + " in site " + _site.Name);
		}
		
		public string InsertItem(ArticleCategory item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("articles_categories_status",item.articles_categories_status);
			post.AddField("articles_categories_order",item.articles_categories_order);
			post.AddField("module", "articles_categories");
			post.AddField("action", "save_articles_category");
			
			foreach(string key in item.articles_categories_names.Keys)
			{
				post.AddField(key,item.articles_categories_names[key]);
			}
			
			foreach(string key in item.articles_categories_urls.Keys)
			{
				post.AddField(key,item.articles_categories_urls[key]);
			}

			foreach(string key in item.page_titles.Keys)
			{
				post.AddField(key,item.page_titles[key]);
			}

			foreach(string key in item.meta_keywordss.Keys)
			{
				post.AddField(key,item.meta_keywordss[key]);
			}		
			
			foreach(string key in item.meta_descriptions.Keys)
			{
				post.AddField(key,item.meta_descriptions[key]);
			}	
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						if (bool.Parse(json[key].ToString())) {
							
							var categories = DownloadItems();
							
							foreach(ArticleCategory category in categories)
							{
								var _category = LoadItem(category.articles_categories_id);
								
								if(_category == null)
								{
									PersistItem(category);
									return category.articles_categories_id;
								}
							}
						}
					}
				}
			}

			throw new Exception("Could not insert the ArticleCategory " + item.articles_categories_name + " in site " + _site.Name);
		}
	}
}
